package yto.freemarker.springbootstudy.jsonwebtoken;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.google.common.collect.Maps;

import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * 加密和效验的代码
 *
 * @author dongxing
 * @create 2018-05-31 8:40
 **/
public class JwtToken {


    //公共的秘钥，保存在服务器端
    private final static String SECRET = "SHANGHAIYTO";


    /**
     * 生成Token
     *
     * @return
     */
    public static String createToken() throws Exception {
        //签发日期
        Date date = new Date();

        //过期时间
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.MINUTE, 1);
        Date expiresDate = nowTime.getTime();

        Map<String, Object> map = Maps.newHashMap();
        map.put("alg", "HS256");
        map.put("type", "JWT");

        String token = JWT.create()
                .withHeader(map) //header的信息
                .withClaim("name", "张三") //payload的信息
                .withClaim("age", "25")
                .withClaim("city", "上海")
                .withExpiresAt(expiresDate) //设置过期的时间
                .withIssuedAt(date)  //设置签发时间
                .sign(Algorithm.HMAC256(SECRET));   //加密

        return token;
    }

    /**
     * 解密Token
     *
     * @param token
     * @return
     * @throws UnsupportedEncodingException
     */
    public static Map<String, Claim> verifyToken(String token) throws Exception {

        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();

        DecodedJWT jwt = null;

        try {
            jwt = verifier.verify(token);
        } catch (JWTVerificationException e) {
            throw new RuntimeException("登陆凭证已经过期，请重新获取");
        }
        return jwt.getClaims();
    }


    public static void main(String[] args) throws Exception {
        //生成Token
        String token = JwtToken.createToken();

        System.out.println("Token:" + token);

        //解析Token
        Map<String, Claim> map = JwtToken.verifyToken(token);

        System.out.println(map.get("name").asString());
        System.out.println(map.get("age").asString());
        System.out.println(map.get("city") == null ? null : map.get("city").asString());

        //使用过期的Token来效验
        String expireToken = "eyJ0eXBlIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.eyJjaXR5Ijoi5LiK5rW3IiwibmFtZSI6IuW8oOS4iSIsImV4cCI6MTUyNzczMDM5MywiaWF0IjoxNTI3NzMwMzMzLCJhZ2UiOiIyNSJ9.v7fUKV3PNYKH-VsZ3SSpr7AdjmJ-S2DOQZRaRVW6bJA";

        Map<String, Claim> token1 = JwtToken.verifyToken(expireToken);


    }
}
